D:\a\scloud-dns\scloud-dns\src\ui\mod.rs
Line | Count | Source |
1 | | use std::io; |
2 | | |
3 | | use crossterm::event::{self, Event, KeyCode, KeyEvent, KeyEventKind}; |
4 | | use ratatui::{ |
5 | | DefaultTerminal, Frame, |
6 | | buffer::Buffer, |
7 | | layout::Rect, |
8 | | style::Stylize, |
9 | | symbols::border, |
10 | | text::{Line, Text}, |
11 | | widgets::{Block, Paragraph, Widget}, |
12 | | }; |
13 | | |
14 | | #[derive(Debug, Default)] |
15 | | pub struct App { |
16 | | counter: u8, |
17 | | exit: bool, |
18 | | } |
19 | | |
20 | | impl App { |
21 | 0 | pub fn run(&mut self, terminal: &mut DefaultTerminal) -> io::Result<()> { |
22 | 0 | while !self.exit { |
23 | 0 | terminal.draw(|frame| self.draw(frame))?; |
24 | 0 | self.handle_events()?; |
25 | | } |
26 | 0 | Ok(()) |
27 | 0 | } |
28 | | |
29 | 0 | fn draw(&self, frame: &mut Frame) { |
30 | 0 | frame.render_widget(self, frame.area()); |
31 | 0 | } |
32 | | |
33 | 0 | fn handle_events(&mut self) -> io::Result<()> { |
34 | 0 | match event::read()? { |
35 | 0 | Event::Key(key_event) if key_event.kind == KeyEventKind::Press => { |
36 | 0 | self.handle_key_event(key_event) |
37 | | } |
38 | 0 | _ => {} |
39 | | } |
40 | 0 | Ok(()) |
41 | 0 | } |
42 | | |
43 | 0 | fn handle_key_event(&mut self, key_event: KeyEvent) { |
44 | 0 | match key_event.code { |
45 | 0 | KeyCode::Char('q') => self.exit(), |
46 | 0 | KeyCode::Left => self.decrement_counter(), |
47 | 0 | KeyCode::Right => self.increment_counter(), |
48 | 0 | _ => {} |
49 | | } |
50 | 0 | } |
51 | | |
52 | 0 | fn exit(&mut self) { |
53 | 0 | self.exit = true; |
54 | 0 | } |
55 | | |
56 | 0 | fn increment_counter(&mut self) { |
57 | 0 | self.counter += 1; |
58 | 0 | } |
59 | | |
60 | 0 | fn decrement_counter(&mut self) { |
61 | 0 | self.counter -= 1; |
62 | 0 | } |
63 | | } |
64 | | |
65 | | impl Widget for &App { |
66 | 0 | fn render(self, area: Rect, buf: &mut Buffer) { |
67 | 0 | let title = Line::from(" Counter App Tutorial ".bold()); |
68 | 0 | let instructions = Line::from(vec![ |
69 | 0 | " Decrement ".into(), |
70 | 0 | "<Left>".blue().bold(), |
71 | 0 | " Increment ".into(), |
72 | 0 | "<Right>".blue().bold(), |
73 | 0 | " Quit ".into(), |
74 | 0 | "<Q> ".blue().bold(), |
75 | | ]); |
76 | | |
77 | 0 | let block = Block::bordered() |
78 | 0 | .title(title.centered()) |
79 | 0 | .title_bottom(instructions.centered()) |
80 | 0 | .border_set(border::THICK); |
81 | | |
82 | 0 | let counter_text = Text::from(vec![Line::from(vec![ |
83 | 0 | "Value: ".into(), |
84 | 0 | self.counter.to_string().yellow(), |
85 | | ])]); |
86 | | |
87 | 0 | Paragraph::new(counter_text) |
88 | 0 | .centered() |
89 | 0 | .block(block) |
90 | 0 | .render(area, buf); |
91 | 0 | } |
92 | | } |